package com.sudoku.common;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.regex.Pattern;

import javax.swing.JTextField;

import com.alibaba.fastjson.JSONArray;

public class Utils {
	/**
	 * @param min - 包含
	 * @param max - 不包含
	 */
	public static int randint(int min, int max ) {
		return (int)(Math.random()*(max-min)+min);
	}
	
	/**
	 * @return 一个随机排列的1-n序列
	 */
	public static int[] randintList(int n) {
		List<Integer> list = new ArrayList<>();
		for (int i = 1; i <= n; i++) {
			list.add(i);
		}
		
		int[] result = new int[list.size()];
		int p = 0;
		while (!list.isEmpty()) {
			int x = randint(0, list.size());
			result[p++] = list.get(x);
			list.remove(x);
		}
		
		return result;
	}
	
	/**
	 * @param seed 数独终盘种子
	 * @param p 映射方法
	 * @return 映射后的数独终盘
	 */
	private static int[][] swapSukodu(int[][] seed, int[] p) {
		int[] mapper = new int[9];
		for (int i = 0; i < p.length; i++) {
			mapper[p[i]-1] = p[(i+1)%9]; 
		}
		
		int[][] result = new int[9][9];
		
		for (int i = 0; i < 9; i++) {
			for (int j = 0; j < 9; j++ ) {
				result[i][j] = mapper[seed[i][j]-1];
			}
		}
		return result;
	}
	
	/**
	 * @return 逆时针旋转矩阵90度
	 */
	private static int[][] rotateSukodu(int[][] seed) {
		int[][] result = new int[9][9];
		for (int row = 0; row < 9; row++) {
			for (int col = 0; col < 9; col++) {
				result[row][col] = seed[col][8-row];
			}
		}
		return result;
	}

	// 生成随机数独终盘
	public static int[][] generateSukodu() {		
		int[][] result = swapSukodu(Constants.SEED, randintList(9));
		int rN = randint(1, 4); // 旋转次数
		for (int i = 0; i<rN; i++) {
			result = rotateSukodu(result);			
		}
		return result;
	}

	public static boolean[][] generateMask(int difficultLevel) {
		double ratio = 0;
		boolean[][] mask = new boolean[Constants.GRID_SIZE][Constants.GRID_SIZE];
		switch(difficultLevel) {
			case Constants.VALUE_EASY:
				ratio = Constants.RATIO_EASY;
				break;
			case Constants.VALUE_INTERMEDIATE:
				ratio = Constants.RATIO_INTERMEDIATE;
				break;
			case Constants.VALUE_DIFFFICULT:
				ratio = Constants.RATIO_DIFFICULT;
				break;
			default:
				ratio = Constants.RATIO_INTERMEDIATE;
				break;
		}
		for (int row = 0; row<9; row++) {
			for (int col = 0; col<9; col++) {
				if (Math.random() <= ratio) {
					mask[row][col] = false;
				} else {
					mask[row][col] = true;
				}
			}
		}
		return mask;
	}
	
	// 判断字符串是否是整数
	public static boolean isInteger(String str) {
		if (str==null || "".equals(str.trim())) {
			return false;
		} else {
			Pattern pattern = Pattern.compile("^[-\\+]?[\\d]*$");  
			return pattern.matcher(str).matches();  			
		}
	}

	// 获取二维boolean数组中true的个数
	public static int getTrueCnt(boolean[][] mask) {
		int cnt = 0;
		for (int row = 0; row < mask.length; row++) {
			for (int col = 0; col < mask[row].length; col++) {
				if (mask[row][col] == true) {
					cnt++;
				}
			}
		}
		return cnt;
	}
	
	/**
	 * 数组转为字符串
	 */
	public static String tfCells2Json(JTextField[][] jTextFields) {
		String[][] array = new String[Constants.GRID_SIZE][Constants.GRID_SIZE];
		for (int row = 0; row<Constants.GRID_SIZE; row++) {
			for (int col=0; col<Constants.GRID_SIZE; col++) {
				array[row][col] = jTextFields[row][col].getText();
			}
		}

		Object obj = JSONArray.toJSON(array);
		return obj.toString();
	}

	// 将一个boolean[][]类型转化为字符串
	public static String mask2Json(boolean[][] mask) {
		Object obj = JSONArray.toJSON(mask);
		String json = obj.toString();
		return json;
	}


	public static String puzzle2Json(int[][] puzzle) {
		Object obj = JSONArray.toJSON(puzzle);
		return obj.toString();
	}


	/**
	 * 字符串转为数组
	 */
	public static boolean[][] json2mask(String json) {
		return JSONArray.parseObject(json, boolean[][].class);
	}
	
	public static int[][] json2puzzle(String json) {
		return JSONArray.parseObject(json, int[][].class);
	}

	public static String[][] json2TfCells(String json) {
		return JSONArray.parseObject(json, String[][].class);
	}

    public static String getNow() {
        Calendar cal = Calendar.getInstance();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return dateFormat.format(cal.getTime());
    }

    public static boolean exists(String path) {
    	File file = new File(path);
    	return file.exists();
    }
    
    public static void mkStaticDir() {
    	File file = new File("config");
    	if (!file.exists()) {
    		file.mkdirs();
    	}
    }
}
